﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using Douban.Api.Authorization;
using Douban.Api.Infrastructure;
using Douban.Api.Mail;
using Douban.Api.User;
using Douban.Api.Web;
using Microsoft.Practices.Unity;
using System.Configuration;
using Douban.Api.Broadcast;

namespace Douban.Api
{
    public class DoubanService
    {
        private MailServiceProvider _mailService;
        private UserServiceProvider _userService;
        private BroadcastServiceProvider _broadcastService;
        private AuthorizationServiceProvider _authorizationService;
        private DoubanContext _context;

        public const string ConsumerKey = "0306154d8776e70d09123fe89664b527";
        public const string ConsumerSecret = "d3fd2466b62b414d";

        public DoubanService()
        {
            IsRunning = false;
            InitializeContext();
            RegisterServices();
        }

        public static DoubanService Current { get; set; }

        public bool IsRunning { get; private set; }

        public MailServiceProvider MailService
        {
            get
            {
                CheckRunningState();

                if(_mailService == null)
                {
                    _mailService = new MailServiceProvider();
                    _mailService.Context = _context;
                }

                return _mailService;
            }
        }

        public UserServiceProvider UserService
        {
            get
            {
                CheckRunningState();

                if(_userService == null)
                {
                    _userService = new UserServiceProvider();
                    _userService.Context = _context;
                }

                return _userService;
            }
        }

        public BroadcastServiceProvider BroadcastService 
        {
            get
            {
                CheckRunningState();

                if (_broadcastService == null)
                {
                    _broadcastService = new BroadcastServiceProvider();
                    _broadcastService.Context = _context;
                }

                return _broadcastService;
            }
        }

        public AuthorizationServiceProvider AuthorizationService
        {
            get
            {
                CheckRunningState();

                if(_authorizationService == null)
                {
                    _authorizationService = _context.Container.Resolve<AuthorizationServiceProvider>();
                    _authorizationService.Context = _context;
                }

                return _authorizationService;
            }
        }

        public void Run()
        {
            IsRunning = true;
            Current = this;
        }

        private void InitializeContext()
        {
            _context = new DoubanContext();
            _context.Container = new UnityContainer();
            _context.MainService = this;
        }

        private void RegisterServices()
        {
            _context.Container
                .RegisterInstance(_context)
                .RegisterInstance<ConsumerBase>(new DesktopConsumer(ConsumerKey, ConsumerSecret))
                .RegisterType<AuthorizationServiceProvider>()
                .RegisterType<OAuthAuthorization, DesktopOAuthAuthorization>()
                .RegisterType<IDataSourcePool, DataSourcePool>()
                .RegisterType<IAccessTokenManager, FileSystemAccessTokenManager>();
        }

        private void CheckRunningState()
        {
            if (!IsRunning)
                throw new InvalidOperationException("Douban service haven't running, calling DoubanService.Run() first");
        }
    }
}
